#include "ray.h"

Ray::Ray()
: minDistance(0), maxDistance(1)
{
    SetVec3f(origin, 0, 0, 0);
    SetVec3f(direction, 0, 0, -1);
}

Ray::Ray(Vec3f start, Vec3f end)
: minDistance(0), maxDistance(1)
{
    SetVec3f(origin, start);
    SubtractVec3f(direction, end, start);
}

Ray::Ray(const Ray& in)
: minDistance(in.minDistance), maxDistance(in.maxDistance)
{
    SetVec3f(origin, in.origin);
    SetVec3f(direction, in.direction);
}

Ray& Ray::operator=(const Ray& in)
{
    SetVec3f(origin, in.origin);
    SetVec3f(direction, in.direction);
    minDistance = in.minDistance;
    maxDistance = in.maxDistance;
    return *this;
}

bool Ray::intersect(const BoundingBox& boundingBox, float& distance, Vec3f intersectionOut)
{
    bool intersects = false;
    
    if (boundingBox.isPlane()) {
        float D = -boundingBox.min[2];
        float t = (-D - origin[2]) / direction[2];
        
        if (t >= 0.0 && t <= 1.0) {
            Vec3f scaledDirection;
            ScaleVec3f(scaledDirection, direction, t);
            AddVec3f(intersectionOut, origin, scaledDirection);
            
            intersects = boundingBox.contains(intersectionOut);
            if (intersects)
                distance = t;
        }
    }
    
    return intersects;
}

void Ray::getPoint(Vec3f out, float depth) const
{
    float t = (depth - origin[2]) / direction[2];
    Vec3f scaledDirection;
    ScaleVec3f(scaledDirection, direction, t);
    AddVec3f(out, origin, scaledDirection);
}
